package com.base.myproject.client.HR.attendance;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import com.base.myproject.client.busi.BaseStore;
import com.base.myproject.client.busi.BaseTreeStore;
import com.base.myproject.client.busi.Editdisable;
import com.base.myproject.client.busi.BO.BusiObject;
import com.base.myproject.client.busi.BO.TreeNodeModelData;
import com.base.myproject.client.jdbc.DataSet;
import com.base.myproject.client.jdbc.StoreInfo;
import com.base.myproject.client.system.BaseResource;
import com.base.myproject.client.tools.CommandSyncContainer;
import com.base.myproject.client.tools.CommandSyncReturnObject;
import com.base.myproject.client.tools.CommandSyncsql;
import com.base.myproject.client.tools.GreetingService;
import com.base.myproject.client.tools.GreetingServiceAsync;
import com.base.myproject.client.tools.Tools;
import com.base.myproject.client.ui.BaseGrid;
import com.base.myproject.client.ui.BaseJDBCPanel;
import com.base.myproject.client.ui.celleditor.BaseComboBoxForm;
import com.base.myproject.client.ui.celleditor.BaseComboBoxX;
import com.extjs.gxt.ui.client.GXT;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.LayoutRegion;
import com.extjs.gxt.ui.client.Style.SelectionMode;
import com.extjs.gxt.ui.client.Style.VerticalAlignment;
import com.extjs.gxt.ui.client.data.BaseModelData;
import com.extjs.gxt.ui.client.data.ModelType;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MenuEvent;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.event.TreePanelEvent;
import com.extjs.gxt.ui.client.store.Store;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.HorizontalPanel;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.TabPanel;
import com.extjs.gxt.ui.client.widget.VerticalPanel;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.CheckBox;
import com.extjs.gxt.ui.client.widget.form.CheckBoxGroup;
import com.extjs.gxt.ui.client.widget.form.DateField;
import com.extjs.gxt.ui.client.widget.form.DateTimePropertyEditor;
import com.extjs.gxt.ui.client.widget.form.FieldSet;
import com.extjs.gxt.ui.client.widget.form.NumberField;
import com.extjs.gxt.ui.client.widget.form.StoreFilterField;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.grid.CellEditor;
import com.extjs.gxt.ui.client.widget.grid.CheckBoxSelectionModel;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
import com.extjs.gxt.ui.client.widget.menu.Menu;
import com.extjs.gxt.ui.client.widget.menu.MenuItem;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanelSelectionModel;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel.CheckCascade;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel.CheckNodes;
import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.gwt.user.client.ui.Label;

/**
 * 
 * @author 封存操作
 * 2011-1-7
 * 
 */
public class Att_Sealed extends BaseJDBCPanel {
	// 创建一个TabPanel
	String code = "";

	String tree_depcode = null;// 讲当前树形结构中选中的部门id保存
	String tree_de_name = null;// 讲当前树形结构中选中的部门name保存

	TabPanel tabPanel = null;
	TreePanel<TreeNodeModelData> treePanel = null;
	// 创建树形结构的数据表
	BaseTreeStore<TreeNodeModelData> treeStore = null;

	Button day_seal = new Button("封存");
	Button day_seal_cancel = new Button("解封");
	DateField seach_day_seal = new DateField();// 查询日期
	
	Button day_work = new Button("封存");
	Button day_work_cancel = new Button("解封");
	DateField seach_day_work = new DateField();// 查询日期

	public Att_Sealed() {
		seach_day_seal.setPropertyEditor(new DateTimePropertyEditor(
				"yyyy-MM-dd"));
		seach_day_work.setPropertyEditor(new DateTimePropertyEditor(
		"yyyy-MM-dd"));
		seach_day_work.setToolTip("加班/补休封存的终止日期");
		seach_day_seal.setToolTip("排班封存的终止日期");
		
		day_seal.setToolTip("封存选中日期(包含选中日期)之前的数据");
		day_seal_cancel.setToolTip("解封选中日期之后的数据");
		day_work.setToolTip("封存选中日期(包含选中日期)之前的数据");
		day_work_cancel.setToolTip("解封选中日期之后的数据");
		day_seal.addListener(Events.OnClick, getListener());
		day_work.addListener(Events.OnClick, getListener());
		day_work_cancel.addListener(Events.OnClick, getListener());
		day_seal_cancel.addListener(Events.OnClick, getListener());
		init();
	}

	public void init() {
		initTreePanel();
		initWeigetx();
	}

	public void complete() {
		super.complete();
	}

	ContentPanel leftCenter;

	private void initWeigetx() {

		// 垂直布局
		VerticalPanel vp = new VerticalPanel();
		vp.setSpacing(3);
		vp.setHeight(505);

		FieldSet s = new FieldSet();
		s.setHeading("排班封存");

		HorizontalPanel scheduli = new HorizontalPanel();
		scheduli.setHorizontalAlign(HorizontalAlignment.LEFT);
		scheduli.setVerticalAlign(VerticalAlignment.MIDDLE);
		scheduli.add(new Label("排班封存日期："));
		scheduli.add(seach_day_seal);
		scheduli.add(day_seal);
		scheduli.add(day_seal_cancel);
		s.add(scheduli);
		s.setWidth(700);
		
		FieldSet work = new FieldSet();
		work.setHeading("加班/补休封存");

		HorizontalPanel hp_work = new HorizontalPanel();
		hp_work.setHorizontalAlign(HorizontalAlignment.LEFT);
		hp_work.setVerticalAlign(VerticalAlignment.MIDDLE);
		hp_work.add(new Label("加班/补休封存日期："));
		hp_work.add(seach_day_work);
		hp_work.add(day_work);
		hp_work.add(day_work_cancel);
		work.add(hp_work);
		work.setWidth(700);

		vp.add(s);
		vp.add(work);

		BorderLayoutData centerData = new BorderLayoutData(LayoutRegion.CENTER);
		centerData.setMargins(new Margins(5, 0, 5, 0));

		ContentPanel center = new ContentPanel();
		BorderLayout layout = new BorderLayout();
		center.setLayout(layout);
		center.setHeaderVisible(false);
		center.setBodyBorder(false);
		center.add(vp);

		BorderLayoutData northData = new BorderLayoutData(LayoutRegion.WEST,
				200);
		northData.setSplit(true);
		northData.setCollapsible(true);
		northData.setMargins(new Margins(5, 0, 5, 0));

		ContentPanel panel = new ContentPanel();
		panel.setHeading("选择部门");
		panel.add(getTreePanel());
		add(panel, northData);
		add(center, centerData);
	}

	TreePanel<TreeNodeModelData> getTreePanel() {
		if (treePanel == null) {
			initTreePanel();
		}
		return treePanel;
	}

	BaseTreeStore<TreeNodeModelData> getTreeStore() {
		if (treeStore == null) {
			initTreeStore();
		}
		return treeStore;
	}

	// 创建数据连接表
	BaseTreeStore<TreeNodeModelData> initTreeStore() {
		StoreInfo si = new StoreInfo();
		si
				.setSql("select icode,id,name from SystemInfo where id is not null order by id asc");
		si.setTreesortcolumn("id");
		si.setKeyname(new String[] { "icode" });
		si.setTablename("SystemInfo");
		treeStore = new BaseTreeStore<TreeNodeModelData>(si, false);
		treeStore.load();
		return treeStore;

	}

	// 实例化TreePanel
	TreePanelSelectionModel<TreeNodeModelData> tpsm = new TreePanelSelectionModel<TreeNodeModelData>();

	void initTreePanel() {
		treePanel = new TreePanel<TreeNodeModelData>(getTreeStore());
		treePanel.setWidth(200);
		treePanel.setHeight(465);
		treePanel.setDisplayProperty("name");
		treePanel.setSelectionModel(tpsm);
		treePanel.setCheckStyle(CheckCascade.PARENTS);
		treePanel.getStyle().setLeafIcon(
				AbstractImagePrototype
						.create(BaseResource.INSTANCE.tree_file()));
		treePanel.setCheckNodes(CheckNodes.BOTH);
		treePanel.setCheckable(false);
		treePanel.setAutoLoad(true);

		treePanel.addListener(Events.OnClick,
				new Listener<TreePanelEvent<TreeNodeModelData>>() {
					public void handleEvent(TreePanelEvent<TreeNodeModelData> be) {
						if (be.getItem() == null) return;
						tree_depcode = be.getItem().get("id").toString();
					}
				});
	}

	public void setCheckNodes(CheckNodes checkNodes) {
		treePanel.setCheckNodes(checkNodes);
	}

	int sync = 0;
	Listener<BaseEvent> defaultlistener;

	Listener<BaseEvent> getListener() {
		if (defaultlistener != null) {
			return defaultlistener;
		}
		defaultlistener = new Listener<BaseEvent>() {
			public void handleEvent(BaseEvent be) {
				sync++;

				try {
					if (sync == 1) {
						if (be.getType() == Events.OnClick) {
							if (tree_depcode == null) {
								MessageBox.alert("提示", "部门为空，请选择部门，再进行操作，谢谢", null);
								return;
							}
							
							if (be.getSource() == day_seal) {
								if (seach_day_seal.getRawValue().equals("")) {
									MessageBox.alert("提示", "排班封存日期不能为空", null);
									return;
								}
								updateReadOnly();
							} else if (be.getSource() == day_work) {
								if (seach_day_work.getRawValue().equals("")) {
									MessageBox.alert("提示", "加班/补休封存日期不能为空", null);
									return;
								}
								
								//封存包括请半天假在内的所有数据
								String sql = "update hr_Attendance_ot set readOnly=1 where isnull(useDate, '2050-01-01') <= '" + seach_day_work.getRawValue() + "' and depcode like '" + tree_depcode + "%'";
								List<String> list = new ArrayList<String>();
								list.add(sql);
								updateSeal(list);
							} else if (be.getSource() == day_seal_cancel) {
								if (seach_day_seal.getRawValue().equals("")) {
									MessageBox.alert("提示", "排班封存日期不能为空", null);
									return;
								}
								
								cancelReadOnly();
							} else {
								if (seach_day_work.getRawValue().equals("")) {
									MessageBox.alert("提示", "加班/补休封存日期不能为空", null);
									return;
								}
								
								String sql = "update hr_Attendance_ot set readOnly=0 where isnull(useDate, '2000-01-01') > '" + seach_day_work.getRawValue() + "' and depcode like '" + tree_depcode + "%'";
								List<String> list = new ArrayList<String>();
								list.add(sql);
								updateSeal(list);
							}
						}
					}
				} finally {
					sync--;
				}
			}

		};
		return defaultlistener;
	}
	
	private int getMonthMaxDay(int year, int month) {
		int days = 0;
		if (month != 2) {
			switch (month) {
			case 1:
			case 3:
			case 5:
			case 7:
			case 8:
			case 10:
			case 12:
				days = 31;
				break;
			case 4:
			case 6:
			case 9:
			case 11:
				days = 30;
			}
		} else {
			if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
				days = 29;
			else
				days = 28;
		}
		
		return days;
	}

	/**
	 * 这个方法主要用于封存排班信息的，根据用户选中的日期，去设置排班信息中的这个日期之前（包含这个日期）的所有数据为
	 * 只读的。并且要注意的一点就是如果选了每个月的最后一天要做下处理，因为如果选中的日期为最后一天的
	 * 话，那么也就是说moreDayUpdateSql会为初始值，所以不能进行update操作，要去掉这条SQL
	 */
	private void updateReadOnly() {
		int dayField = seach_day_seal.getValue().getDate();
		String newDate = seach_day_seal.getRawValue().substring(0, 7) + "-01";
		
		String lessDayUpdateSql = "update hr_Attendance_schedule set";
		String moreDayUpdateSql = "update hr_Attendance_schedule set";
		
		for (int i = 1; i <= 31; i++) {
			if (i <= dayField) {
				lessDayUpdateSql = lessDayUpdateSql + " r" + i + "_r = 1,";  //拼接日期，设置一个月中小于选中日期之前的天数的值为只读
			} else {
				moreDayUpdateSql = moreDayUpdateSql + " r" + i + "_r = 1,";  //拼接日期，设置一个月中大于选中日期之前的天数的值为只读
			}
		}
		
		List<String> updateSql = new ArrayList<String>();
		//lessDayUpdateSql为一条完整的SQL了，用来UPDATE所有小于等于选中月份的所有选中天数之前的排班信息为只读的
		lessDayUpdateSql = lessDayUpdateSql.substring(0, lessDayUpdateSql.length() - 1) + " where ym <= '" + newDate + "' and depCode like '" + tree_depcode + "%'";
		updateSql.add(lessDayUpdateSql);
		
		if (!moreDayUpdateSql.equals("update hr_Attendance_schedule set")) {
			//moreDayUpdateSql为一条完整的SQL了，用来UPDATE所有小于选中月份的所有选中天数之后的排班信息为只读的
			moreDayUpdateSql = moreDayUpdateSql.substring(0, moreDayUpdateSql.length() - 1) + " where ym < '" + newDate + "' and depCode like '" + tree_depcode + "%'";
			updateSql.add(moreDayUpdateSql);
		}
		//最后一起更新相关部门的封存时间
		String systemInfoUpdate = "update systeminfo set sealDate = '" + seach_day_seal.getRawValue() + "' where id like '" + tree_depcode + "%'";
		updateSql.add(systemInfoUpdate);
		
		updateSeal(updateSql);
	}
	
	/**
	 * 这个方法主要用于解封排班信息的，根据用户选中的日期，去设置排班信息中的这个日期之后（不包含这个日期）的所有数据为
	 * 可写的。并且要注意的一点就是如果选了每个月的最后一天要做下处理，因为如果选中的日期为最后一天的
	 * 话，那么也就是说moreDayUpdateSql会为初始值，所以不能进行update操作，要去掉这条SQL
	 */
	private void cancelReadOnly() {
		String lessDayUpdateSql = "update hr_Attendance_schedule set";
		String moreDayUpdateSql = "update hr_Attendance_schedule set";

		int dayField = seach_day_seal.getValue().getDate();
		String newDate = seach_day_seal.getRawValue().substring(0, 7) + "-01";
		
		for (int i = 1; i <= 31; i++) {
			if (i <= dayField) {
				lessDayUpdateSql = lessDayUpdateSql + " r" + i + "_r = 0,";
			} else {
				moreDayUpdateSql = moreDayUpdateSql + " r" + i + "_r = 0,";
			}
		}

		List<String> updateSql = new ArrayList<String>();
		//完整的SQL，用于UPDATE大于选中的月份的所有月份在选中日期之前（包含选中日期）的的天数都为可写的
		lessDayUpdateSql = lessDayUpdateSql.substring(0, lessDayUpdateSql.length() - 1) + " where ym > '" + newDate + "' and depCode like '" + tree_depcode + "%'";
		updateSql.add(lessDayUpdateSql);
		
		if (!moreDayUpdateSql.equals("update hr_Attendance_schedule set")) {
			//完整的SQL，用于UPDATE大于等于选中的月份的所有月份在选中日期之后的的天数都为可写的
			moreDayUpdateSql = moreDayUpdateSql.substring(0, moreDayUpdateSql.length() - 1) + " where ym >= '" + newDate + "' and depCode like '" + tree_depcode + "%'";
			updateSql.add(moreDayUpdateSql);
		}
		String systemInfoUpdate = "update systeminfo set sealDate = '" + seach_day_seal.getRawValue() + "' where id like '" + tree_depcode + "%'";
		updateSql.add(systemInfoUpdate);
		
		updateSeal(updateSql);
	}
	
	/**
	 * @param lists
	 *            要执行的sql语句
	 * @return 执行成功与否 执行所有的update语句，完全封存的操作
	 */
	public boolean updateSeal(List<String> lists) {
		CommandSyncsql csql = new CommandSyncsql();// 执行sql命令
		for (String sql : lists) {
			csql.getV().add(sql);
		}
		if (csql.getV().size() <= 0) {
			return false;
		} else {
			CommandSyncContainer list = new CommandSyncContainer();// 可以添加的命令
			list.add(csql);

			 final MessageBox box = MessageBox.wait("封存",  
			            "正在对数据进行封存操作请等待...", "封存操作中...");  
			GreetingServiceAsync greetingService = GWT
					.create(GreetingService.class);
			greetingService.SendCommandSync(list,
					new AsyncCallback<CommandSyncReturnObject>() {
						@Override
						public void onFailure(Throwable caught) {
							MessageBox.alert("错误", "网络连接失败", null);
						}

						@Override
						public void onSuccess(CommandSyncReturnObject result) {
							if (result.isB()) {
								box.close();
								Info.display("提示信息", "操作成功");
							} else {
								MessageBox.alert("错误", "错误，错误代码"
										+ result.getMessage(), null);

							}
						}
					});
		}
		return true;
	}
}
